home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP11.ZIP / CHAP11 / POLYLINE / IPOLYLIN.CPP < prev    next >
C/C++ Source or Header  |  1993-06-17  |  13KB  |  616 lines

  1. /*
  2.  * IPOLYLIN.CPP
  3.  * Polyline Component Object Chapter 11
  4.  *
  5.  * Implementation of the IPolyline interface that we expose on the
  6.  * CPolyline object.
  7.  *
  8.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Software Design Engineer
  11.  * Microsoft Systems Developer Relations
  12.  *
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  15.  */
  16.  
  17.  
  18. #include "polyline.h"
  19.  
  20.  
  21. /*
  22.  * CImpIPolyline:CImpIPolyline
  23.  * CImpIPolyline::~CImpIPolyline
  24.  *
  25.  * Constructor Parameters:
  26.  *  pObj            LPCPolyline pointing to the object we live in.
  27.  *  punkOuter       LPUNKNOWN of the controlling unknown.
  28.  */
  29.  
  30. CImpIPolyline::CImpIPolyline(LPCPolyline pObj, LPUNKNOWN punkOuter)
  31.     {
  32.     m_cRef=0;
  33.     m_pObj=pObj;
  34.     m_punkOuter=punkOuter;
  35.     return;
  36.     }
  37.  
  38.  
  39. CImpIPolyline::~CImpIPolyline(void)
  40.     {
  41.     return;
  42.     }
  43.  
  44.  
  45.  
  46.  
  47. /*
  48.  * CImpIPolyline::QueryInterface
  49.  * CImpIPolyline::AddRef
  50.  * CImpIPolyline::Release
  51.  *
  52.  * Purpose:
  53.  *  Standard set of IUnknown members for this interface
  54.  */
  55.  
  56. STDMETHODIMP CImpIPolyline::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  57.     {
  58.     return m_punkOuter->QueryInterface(riid, ppv);
  59.     }
  60.  
  61. STDMETHODIMP_(ULONG) CImpIPolyline::AddRef(void)
  62.     {
  63.     ++m_cRef;
  64.     return m_punkOuter->AddRef();
  65.     }
  66.  
  67. STDMETHODIMP_(ULONG) CImpIPolyline::Release(void)
  68.     {
  69.     --m_cRef;
  70.     return m_punkOuter->Release();
  71.     }
  72.  
  73.  
  74.  
  75.  
  76.  
  77. /*
  78.  * CImpIPolyline::Init
  79.  *
  80.  * Purpose:
  81.  *  Instantiates a polyline window within a given parent.  The
  82.  *  parent may be a main application window, could be an MDI child
  83.  *  window. We really do not care.
  84.  *
  85.  * Parameters:
  86.  *  hWndParent      HWND of the parent of this window
  87.  *  pRect           LPRECT that this window should occupy
  88.  *  dwStyle         DWORD containing the window's style flags
  89.  *  uID             UINT ID to associate with this window
  90.  *
  91.  * Return Value:
  92.  *  HRESULT         NOERROR if successful, otherwise E_OUTOFMEMORY
  93.  */
  94.  
  95. STDMETHODIMP CImpIPolyline::Init(HWND hWndParent, LPRECT pRect
  96.     , DWORD dwStyle, UINT uID)
  97.     {
  98.     SCODE           sc;
  99.  
  100.     m_pObj->m_hWnd=CreateWindowEx(WS_EX_NOPARENTNOTIFY, SZCLASSPOLYLINE
  101.         , SZCLASSPOLYLINE, dwStyle, pRect->left, pRect->top
  102.         , pRect->right-pRect->left, pRect->bottom-pRect->top
  103.         , hWndParent, (HMENU)uID, m_pObj->m_hInst, (LPVOID)m_pObj);
  104.  
  105.  
  106.     sc=(NULL!=m_pObj->m_hWnd) ? S_OK : E_OUTOFMEMORY;
  107.     return ResultFromScode(sc);
  108.     }
  109.  
  110.  
  111.  
  112.  
  113. /*
  114.  * CImpIPolyline::New
  115.  *
  116.  * Purpose:
  117.  *  Cleans out and reinitializes the data to defaults.
  118.  *
  119.  * Parameters:
  120.  *  None
  121.  *
  122.  * Return Value:
  123.  *  HRESULT         NOERROR always
  124.  */
  125.  
  126. STDMETHODIMP CImpIPolyline::New(void)
  127.     {
  128.     LPPOLYLINEDATA  ppl=&m_pObj->m_pl;
  129.     UINT            i;
  130.  
  131.     ppl->wVerMaj=VERSIONMAJOR;
  132.     ppl->wVerMin=VERSIONMINOR;
  133.  
  134.     //Our rectangle is the size of our window's client area.
  135.     //CHAPTER11MOD
  136.     if (NULL!=m_pObj->m_hWnd)
  137.         GetClientRect(m_pObj->m_hWnd, &ppl->rc);
  138.     else
  139.         SetRect(&ppl->rc, 0, 0, 100, 100);  //Something reasonable
  140.     //End CHAPTER11MOD
  141.  
  142.     //Clean out the POLYLINEDATA structure and repaint the window.
  143.     for (i=0; i< CPOLYLINEPOINTS; i++)
  144.         {
  145.         ppl->rgpt[i].x=0;
  146.         ppl->rgpt[i].y=0;
  147.         }
  148.  
  149.     ppl->cPoints      =0;
  150.     ppl->rgbBackground=GetSysColor(COLOR_WINDOW);
  151.     ppl->rgbLine      =GetSysColor(COLOR_WINDOWTEXT);
  152.     ppl->iLineStyle   =PS_SOLID;
  153.  
  154.     //CHAPTER11MOD
  155.     //This is now conditional since we may not yet have a window.
  156.     if (NULL!=m_pObj->m_hWnd)
  157.         {
  158.         InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  159.         UpdateWindow(m_pObj->m_hWnd);
  160.         m_pObj->m_fDirty=TRUE;
  161.         }
  162.  
  163.     m_pObj->SendAdvise(OBJECTCODE_DATACHANGED);
  164.     //End CHAPTER11MOD
  165.  
  166.     return NOERROR;
  167.     }
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174. /*
  175.  * CImpIPolyline::Undo
  176.  *
  177.  * Purpose:
  178.  *  Reverses previous actions in a Polyline.
  179.  *
  180.  * Parameters:
  181.  *  None
  182.  *
  183.  * Return Value:
  184.  *  HRESULT         S_OK if we can Undo more, S_FALSE otherwise.
  185.  */
  186.  
  187. STDMETHODIMP CImpIPolyline::Undo(void)
  188.     {
  189.     SCODE           sc;
  190.  
  191.     //Decrement the number of active points and repaint.
  192.     if (m_pObj->m_pl.cPoints > 0)
  193.         {
  194.         m_pObj->m_pl.cPoints--;
  195.         InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  196.         UpdateWindow(m_pObj->m_hWnd);
  197.         }
  198.  
  199.     if (NULL!=m_pObj->m_pAdv)
  200.         {
  201.         m_pObj->m_fDirty=TRUE;
  202.         m_pObj->m_pAdv->OnPointChange();
  203.         }
  204.  
  205.     //CHAPTER11MOD
  206.     m_pObj->SendAdvise(OBJECTCODE_DATACHANGED);
  207.     //End CHAPTER11MOD
  208.  
  209.     //Return if we can undo any more.
  210.     sc=(0!=m_pObj->m_pl.cPoints) ? S_OK : S_FALSE;
  211.     return ResultFromScode(sc);
  212.     }
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219. /*
  220.  * CImpIPolyline::Window
  221.  *
  222.  * Purpose:
  223.  *  Returns the window handle associated with this polyline.
  224.  *
  225.  * Parameters:
  226.  *  phWnd           HWND FAR * in which to return the window handle.
  227.  *
  228.  * Return Value:
  229.  *  HRESULT         NOERROR always.
  230.  */
  231.  
  232. STDMETHODIMP CImpIPolyline::Window(HWND FAR *phWnd)
  233.     {
  234.     *phWnd=m_pObj->m_hWnd;
  235.     return NOERROR;
  236.     }
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243. /*
  244.  * CImpIPolyline::SetAdvise
  245.  *
  246.  * Purpose:
  247.  *  Provides this object with an IPolylineAdviseSink that's interested
  248.  *  in our notifications.  We AddRef and store this pointer, Releasing
  249.  *  the old one.
  250.  *
  251.  * Parameters:
  252.  *  pAdv            LPPOLYLINEADVISESINK to notify.
  253.  *
  254.  * Return Value:
  255.  *  HRESULT         NOERROR always.
  256.  */
  257.  
  258. STDMETHODIMP CImpIPolyline::SetAdvise(LPPOLYLINEADVISESINK pAdv)
  259.     {
  260.     if (NULL!=m_pObj->m_pAdv)
  261.         m_pObj->m_pAdv->Release();
  262.  
  263.     m_pObj->m_pAdv=pAdv;
  264.  
  265.     if (NULL!=m_pObj->m_pAdv)
  266.         m_pObj->m_pAdv->AddRef();
  267.  
  268.     return NOERROR;
  269.     }
  270.  
  271.  
  272.  
  273.  
  274. /*
  275.  * CImpIPolyline::GetAdvise
  276.  *
  277.  * Purpose:
  278.  *  Returns the IPolylineAdviseSink that was last passed to SetAdvise.
  279.  *
  280.  * Parameters:
  281.  *  ppAdv           LPPOLYLINEADVISESINK FAR * in which to return the
  282.  *                  pointer.
  283.  *
  284.  * Return Value:
  285.  *  HRESULT         NOERROR always.
  286.  */
  287.  
  288. STDMETHODIMP CImpIPolyline::GetAdvise(LPPOLYLINEADVISESINK FAR *ppAdv)
  289.     {
  290.     *ppAdv=m_pObj->m_pAdv;
  291.     return NOERROR;
  292.     }
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299. /*
  300.  * CImpIPolyline::RectGet
  301.  *
  302.  * Purpose:
  303.  *  Returns the rectangle of the Polyline in parent coordinates.
  304.  *
  305.  * Parameters:
  306.  *  pRect           LPRECT in which to return the rectangle.
  307.  *
  308.  * Return Value:
  309.  *  HRESULT         NOERROR always
  310.  */
  311.  
  312. STDMETHODIMP CImpIPolyline::RectGet(LPRECT pRect)
  313.     {
  314.     RECT            rc;
  315.     POINT           pt;
  316.  
  317.     //Retrieve the size of our rectangle in parent coordinates.
  318.     GetWindowRect(m_pObj->m_hWnd, &rc);
  319.     pt.x=rc.left;
  320.     pt.y=rc.top;
  321.     ScreenToClient(GetParent(m_pObj->m_hWnd), &pt);
  322.  
  323.     SetRect(pRect, pt.x, pt.y, pt.x+(rc.right-rc.left)
  324.         , pt.y+(rc.bottom-rc.top));
  325.  
  326.     return NOERROR;
  327.     }
  328.  
  329.  
  330.  
  331.  
  332.  
  333. /*
  334.  * CImpIPolyline::SizeGet
  335.  *
  336.  * Purpose:
  337.  *  Retrieves the size of the Polyline in parent coordinates.
  338.  *
  339.  * Parameters:
  340.  *  pRect           LPRECT in which to return the size.  The right and
  341.  *                  bottom fields will contain the dimensions.
  342.  *
  343.  * Return Value:
  344.  *  HRESULT         NOERROR always
  345.  */
  346.  
  347. STDMETHODIMP CImpIPolyline::SizeGet(LPRECT pRect)
  348.     {
  349.     RectGet(pRect);
  350.     return NOERROR;
  351.     }
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358. /*
  359.  * CImpIPolyline::RectSet
  360.  *
  361.  * Purpose:
  362.  *  Sets a new rectangle for the Polyline which sizes to fit.
  363.  *
  364.  * Parameters:
  365.  *  pRect           LPRECT containing the new rectangle.
  366.  *  fNotify         BOOL indicating if we're to notify anyone of the change.
  367.  *
  368.  * Return Value:
  369.  *  HRESULT         NOERROR always
  370.  */
  371.  
  372. STDMETHODIMP CImpIPolyline::RectSet(LPRECT pRect, BOOL fNotify)
  373.     {
  374.     UINT            cx, cy;
  375.  
  376.     //Scale the points from our current size to the new size
  377.     cx=pRect->right-pRect->left;
  378.     cy=pRect->bottom-pRect->top;
  379.  
  380.     SetWindowPos(m_pObj->m_hWnd, NULL, pRect->left, pRect->top
  381.         , (UINT)cx, (UINT)cy, SWP_NOZORDER);
  382.  
  383.     if (fNotify && NULL!=m_pObj->m_pAdv)
  384.         {
  385.         m_pObj->m_f